home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / haeberli / libgutil / rendchar.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  4KB  |  180 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /* 
  18.  *    rendchar - 
  19.  *        convert polygonal outlines into bitmaps
  20.  *
  21.  *    Exports:
  22.  *        Bitmap *polychartobm(chardesc *cd, mat2d *mat,double linewidth);
  23.  *
  24.  *            Paul Haeberli - 1991
  25.  */
  26. #include "bitmap.h"
  27. #include "math.h"
  28. #include "objfnt.h"
  29. #include "polyscan.h"
  30.  
  31. #define FUNC_BEGINFACET 1
  32. #define FUNC_ENDFACET   2
  33. #define FUNC_VERTEX     3
  34.  
  35. static float xmin, xmax;
  36. static float ymin, ymax;
  37. static Bitmap *thebm;
  38.  
  39. void transpoint2(mat2d *mat,double ix,double iy,double *ox,double *oy)
  40. {
  41.     *ox = mat->a*ix+mat->b*iy+mat->tx;
  42.     *oy = mat->c*ix+mat->d*iy+mat->ty;
  43. }
  44.  
  45. static void fillspan(int y, int xmin, int xmax)
  46. {
  47.     int p, pxmin, pxmax;
  48.     short *sptr;
  49.     short mask;
  50.     short *bmbase;
  51.  
  52.     if(xmin == xmax) {
  53.     thebm->base[y*thebm->sper + (xmin >> 4)] |= (0x8000>>(xmin&0xf));
  54.     return;
  55.     }
  56.     pxmin = xmin>>4;
  57.     pxmax = xmax>>4;
  58.     bmbase = thebm->base+(y*thebm->sper);
  59.     if(pxmin == pxmax) {
  60.     mask = (0xffff<<(15-(xmax&0xf))) & (0xffff>>(xmin&0xf));
  61.     sptr = bmbase+pxmin;
  62.     *sptr |= mask;
  63.     } else {
  64.     mask = 0xffff>>(xmin&0xf);
  65.     sptr = bmbase+pxmin;
  66.     *sptr++ |= mask;
  67.     for(p=pxmin+1; p<pxmax; p++) 
  68.         *sptr++ = 0xffff;
  69.     mask = 0xffff<<(15-(xmax&0xf));
  70.     *sptr |= mask;
  71.     }
  72. }
  73.  
  74. static void initminmax(void)
  75. {
  76.     xmin = ymin =  100000.0;
  77.     xmax = ymax = -100000.0;
  78. }
  79.  
  80. static void minmaxfunc(int func, float x, float y)
  81. {
  82.     if(func == FUNC_VERTEX) {
  83.     if(x<xmin)
  84.         xmin = x;
  85.     if(x>xmax)
  86.         xmax = x;
  87.     if(y<ymin)
  88.         ymin = y;
  89.     if(y>ymax)
  90.         ymax = y;
  91.     }
  92. }
  93.  
  94. static void scanfunc(int func, float x, float y)
  95. {
  96.     switch(func) {
  97.     case FUNC_BEGINFACET:
  98.         scanbeginfacet();
  99.         break;
  100.     case FUNC_ENDFACET:
  101.         scanendfacet();
  102.         break;
  103.     case FUNC_VERTEX:
  104.         scanvertex(x,y);
  105.         break;
  106.     }
  107. }
  108.  
  109. static void execcharprog(short *sptr, mat2d *mat, void (*func)(int func, float x, float y))
  110. {
  111.     int nverts;
  112.     double ix, iy, tx, ty;
  113.  
  114.     while(1) {
  115.     switch(*sptr++) {    
  116.         case PO_BGNLOOP:
  117.         func(FUNC_BEGINFACET,0.0,0.0);
  118.         break;
  119.         case PO_ENDBGNLOOP:
  120.         func(FUNC_ENDFACET,0.0,0.0);
  121.         func(FUNC_BEGINFACET,0.0,0.0);
  122.         break;
  123.         case PO_RETENDLOOP:
  124.         func(FUNC_ENDFACET,0.0,0.0);
  125.         return;
  126.         break;
  127.         case PO_RET:
  128.         return;
  129.         break;
  130.     }
  131.     nverts = *sptr++;
  132.     while(nverts--) {
  133.         ix = sptr[0];
  134.         iy = sptr[1];
  135.         transpoint2(mat,ix,iy,&tx,&ty);
  136.         func(FUNC_VERTEX,tx,ty);
  137.         sptr+=2;
  138.     }
  139.     }
  140. }
  141.  
  142. Bitmap *polychartobm(chardesc *cd, mat2d *mat,double linewidth)
  143. {
  144.     int xsize, ysize;
  145.     mat2d mymat;
  146.     float hwidth;
  147.  
  148.     if(cd->data) {
  149.     scanoutspan(fillspan);
  150.     scanoutlinewidth(linewidth);
  151.     hwidth = linewidth/2.0;
  152.     initminmax();
  153.     execcharprog(cd->data,mat,minmaxfunc);
  154.     if(xmin<xmax) {
  155.         xmin = floor(xmin-hwidth);    /* add a bit for the 1/2 pixel bloat */
  156.         ymin = floor(ymin-hwidth);
  157.         xmax = ceil(xmax+hwidth);
  158.         ymax = ceil(ymax+hwidth);
  159.         xsize = xmax-xmin;
  160.         ysize = ymax-ymin;
  161.         if(xsize<1)
  162.         xsize = 1;
  163.         if(ysize<1)
  164.         ysize = 1;
  165.         thebm = bmnew(xsize,ysize);
  166.         thebm->xorig = -xmin;
  167.         thebm->yorig = -ymin;
  168.         mymat = *mat;
  169.         mymat.tx -= (xmin+0.5);
  170.         mymat.ty -= (ymin+0.5);
  171.         scanbeginscan();
  172.         execcharprog(cd->data,&mymat,scanfunc);
  173.         scanendscan();
  174.         return thebm;
  175.     }
  176.     }
  177.     thebm = bmnew(1,1);
  178.     return thebm;
  179. }
  180.